using System;
using System.Threading;

namespace Silent.Parallel
{
    public class WorkingThread
    {
        public event EventHandler<WorkingEventArgs> WorkingStateChanged;
        protected virtual void OnWorkingStateChanged(WorkingEventArgs e)
        {
            EventHandler<WorkingEventArgs> handler = WorkingStateChanged;
            if (handler != null)
                handler(this, e);
        }

        private readonly Thread thread;
        private WorkingState state;
        public WorkingState State
        {
            get { return state; }
            private set
            {
                state = value;
                OnWorkingStateChanged(new WorkingEventArgs(state));
            }
        }
        public Action Action { get; private set; }

        public WorkingThread()
        {
            thread = new Thread(Execute) {IsBackground = true};
        }
        public WorkingThread(Action action) : this()
        {
            Action = action;
        }

        public void Assign(Action action)
        {
            Action = action;
        }
        public WorkingState BeginExecution()
        {
            if (State == WorkingState.Working)
                return State;

            thread.Start();
            return State;
        }
        public WorkingState EndExecution()
        {
            if (State != WorkingState.Working)
                return State;

            while (thread.ThreadState != ThreadState.Stopped)
            {
            }
            return State;
        }
        private void Execute()
        {
            try
            {
                State = WorkingState.Working;

                if (Action != null)
                    Action.Invoke();

                State = WorkingState.Stopped;
                State = WorkingState.Waiting;
            }
            catch (Exception)
            {
                State = WorkingState.Failed;
            }
        }
    }
}